package com.qy33.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;

import com.qy33.entity.Dot;
import com.qy33.entity.Line;
import com.qy33.entity.Line2;
import com.qy33.entity.Stock;


/**
 * 线段的计算逻辑
 * @author Henry
 * @date 2013-1-25
 *
 */
public class LineService extends BaseService {
	
	private DotService dotService = new DotService();
	
	/**
	 * 得到所有双线的图形
	 * @param code
	 * @param list
	 * @return
	 */
	public List<Line2> getAllLine2(String code, List<Stock> list) {
		List<Line2> result = new ArrayList<Line2>();
		List<Line> lines = this.getAllLine(code, list);
		for (int i = 0; i < lines.size(); i++) {
			Line2 line2 = new Line2();
			
			Line begin = lines.get(i);
			if (i + 1 >= lines.size()) {
				break;
			}
			Line end = lines.get(i + 1);
			
			line2.setBegin(begin);
			line2.setEnd(end);
			if (begin.getType() == Line.Type_Up) {
				line2.setType(Line2.Type_UpDown);
			} else {
				line2.setType(Line2.Type_DownUp);
			}
			result.add(line2);
		}
		return result;
	}
	
	/**
	 * 得到所有的线段
	 * @param code
	 * @param list
	 * @return
	 */
	public List<Line> getAllLine(String code, List<Stock> list) {
		/*
		 * 计算线段的办法：
		 * 1. 先得到所有高低点
		 * 2. 按照高低点相邻的方式来构造线段
		 * 
		 */
		if (list == null) {
			list = stockDao.findByCode(code);
		}
		List<Line> lines = new ArrayList<Line>();
		List<Dot> dotList = this.dotService.getAllHighLow(code, list);
		for (int i = 0; i < dotList.size(); i++) {
			Dot begin = dotList.get(i);
			int endIndex = this.findNextDot(begin, i, dotList);
			if (endIndex == -1) {
				continue;
			}
			Dot end = dotList.get(endIndex);
			
			Line line = new Line();
			line.setCode(begin.getCode());
			line.setBegin(begin);
			line.setEnd(end);
			if (begin.getType() == Dot.Type_High) {
				line.setType(Line.Type_Down);
			} else {
				line.setType(Line.Type_Up);
			}
			lines.add(line);
			
			i = endIndex - 1;
		}
		
		/*
		 * 处理可能会出现的错误情况：
		 * 1. 高点连接低点，低点价位比高点还高的
		 * 2. 低点连接高点，高点价位比低点还低的
		 */
		List<Line> result = new ArrayList<Line>();
		for (int i = 0; i < lines.size(); i++){
			Line l = lines.get(i);
			
			if (l.getType() == Line.Type_Up
					&& l.getEnd().getPrice().doubleValue() < l.getBegin().getPrice().doubleValue()) {
				i++;
				continue;
			} else if (l.getType() == Line.Type_Down
					&& l.getEnd().getPrice().doubleValue() > l.getBegin().getPrice().doubleValue()) {
				i++;
				continue;
			}
			result.add(l);
		}
		
		/*
		 * 验证前后对应的点是否对应，如果不对应则直接更换成后面的
		 */
		for (int i = 0; i < result.size(); i++) {
			Line curr = lines.get(i);
			if (i + 1 >= result.size()) {
				continue;
			}
			Line next = lines.get(i + 1);
			
			if (curr.getType() == Line.Type_Up && !curr.getEnd().equals(next.getBegin())) {
				curr.setEnd(next.getBegin());
			}
			if (curr.getType() == Line.Type_Down && !curr.getEnd().equals(next.getBegin())) {
				curr.setEnd(next.getBegin());
			}
		}
		return result;
	}
	
	/**
	 * 找下一节点的方法
	 * @param begin
	 * @param pos
	 * @param dotList
	 * @return
	 */
	private int findNextDot(Dot begin, int pos, List<Dot> dotList) {
		int dotType = begin.getType();
		
		// 先找与begin紧挨着，且与begin不同类型的dot集合
		List<Dot> diffTypeDot = new ArrayList<Dot>();
		int i = pos + 1;
		if (i >= dotList.size()) {
			return -1;
		}
		while (true) {
			Dot next = dotList.get(i);
			if (CollectionUtils.isNotEmpty(diffTypeDot) && next.getType() == dotType) {
				break;
			}
			if (next.getType() == dotType) {
				i++;
				continue;
			} else {
				diffTypeDot.add(next);
			}
			i++;
			if (i >= dotList.size()) {
				break;
			}
		}
		if (CollectionUtils.isEmpty(diffTypeDot)) {
			return -1;
		}
		
		// 排序
		Collections.sort(diffTypeDot, new Comparator<Dot>() {

			@Override
			public int compare(Dot o1, Dot o2) {
				if (o1.getPrice().doubleValue() < o2.getPrice().doubleValue()) {
					return 1;
				} else if (o1.getPrice().doubleValue() > o2.getPrice().doubleValue()) {
					return -1;
				}
				return 0;
			}
		});
		
		// 如果begin是高点，则找 diffTypeDot 中的最低点
		Dot end = null;
		if (dotType == Dot.Type_High) {
			end = diffTypeDot.get(diffTypeDot.size() - 1);
		}
		
		// 如果begin是低点，则找 diffTypeDot 中的最高点
		if (dotType == Dot.Type_Low) {
			end = diffTypeDot.get(0);
		}
		return dotList.indexOf(end);
	}

	public static void main(String[] args) {
		LineService lineService = new LineService();
		
		List<Line> lines = lineService.getAllLine("600537", null);
		for (Line line : lines) {
//			System.out.print(line.getType());
			System.out.println(line);
		}
	}
	
}
